#include "ToolBar.h"
#include <assert.h>
#include <stdio.h>

CToolBar::CToolBar()
{
   m_bLoaded = false;
}

CToolBar::~CToolBar()
{
}

HWND CToolBar::Create(HWND hParent, RECT& rcPos, UINT nToolBarID, DWORD dwCtrlStyle, DWORD dwStyle)
{
   HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle | dwCtrlStyle, 
                              rcPos.left, rcPos.top, rcPos.right - rcPos.left, rcPos.bottom - rcPos.top,
                              hParent, (HMENU)nToolBarID, _Module.GetModuleInstance(), NULL);
   if (hWnd) {
      Attach(hWnd);
   }
   return hWnd;
}
               
struct CToolBarData
{
   WORD wVersion;
   WORD wWidth;
   WORD wHeight;
   WORD wItemCount;
   //WORD aItems[wItemCount]

   WORD* items() { return (WORD*)(this+1); }
};

#define RT_TOOLBAR   (MAKEINTRESOURCE(241))

BOOL CToolBar::LoadToolBar(UINT uBitmapID)
{
   assert(uBitmapID);
   assert (!m_bLoaded);

   int idx;
   BOOL bResult;
   HINSTANCE hInst = _Module.GetModuleInstance();
   HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(uBitmapID), RT_TOOLBAR);
   if (hRsrc == NULL) {
      return FALSE;
   }
   
   HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
   if (hGlobal == NULL) {
      return FALSE;
   }
   CToolBarData* pData = (CToolBarData*)LockResource(hGlobal);
   if (pData == NULL) {
      bResult = FALSE;
      goto err1;
   }
	
   assert(pData->wVersion == 1);

   // set new sizes of the buttons
   bResult = SetBitmapSize(pData->wWidth, pData->wHeight);
   if (!bResult) {
      goto err2;
   }
   bResult = SetButtonSize(pData->wWidth + 7, pData->wHeight + 7);
   if (!bResult) {
      goto err2;
   }
   // load bitmap now that sizes are known by the toolbar control
   idx = LoadBitmap(uBitmapID, pData->wItemCount);
   if (idx == -1) {
      goto err2;
   }	
		
   bResult = AddButtons(idx, pData->items(), pData->wItemCount);
   if (!bResult) {
      goto err2;
   }
   m_bLoaded = true;
err2:
	UnlockResource(hGlobal);
err1:	
	FreeResource(hGlobal);
	return bResult;
}

BOOL CToolBar::SetBitmapSize(WORD wWidth, WORD wHeight)
{
   assert (::IsWindow(m_hWnd));
   return SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELONG(wWidth, wHeight));
}

BOOL CToolBar::SetButtonSize(WORD wWidth, WORD wHeight)
{
   assert (::IsWindow(m_hWnd));
   m_uButtonWidth = wWidth;
   m_uButtonHeight = wHeight;

   return SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELONG(wWidth, wHeight));
}

int CToolBar::LoadBitmap(UINT uBitmapID, WORD wCount)
{
   assert (::IsWindow(m_hWnd));
   assert (!m_bLoaded);
   assert (uBitmapID);
   
   TBADDBITMAP tb;
   tb.hInst = _Module.GetModuleInstance();
   tb.nID = uBitmapID;
   return SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)2, (LPARAM)&tb);
}

BOOL CToolBar::AddButtons(int idxBitmap, const WORD* pwID, WORD wCount)
{
   assert (wCount);
   assert (idxBitmap >= 0);
   
   TBBUTTON* lptbs;
   int i;
   SendMessage(m_hWnd,TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON),0);

   lptbs = new TBBUTTON[wCount];
   if (!lptbs) {
      return FALSE;
   }
   
   memset (lptbs, 0, sizeof (TBBUTTON) * wCount);
   WORD wSubIdx = 0;
   for (i = 0; i < wCount; i++) {
      lptbs[i].idCommand = pwID[i];
      if (pwID [i] == 0 ) {
         lptbs[i].fsStyle = TBSTYLE_SEP;
         lptbs[i].fsState = TBSTATE_ENABLED | TBSTYLE_AUTOSIZE;
        continue;
      }
      lptbs[i].iBitmap = MAKELONG(wSubIdx++, idxBitmap);
      lptbs[i].fsState = TBSTATE_ENABLED;
      lptbs[i].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
   }
   BOOL bRet = SendMessage(m_hWnd, TB_ADDBUTTONS, (WPARAM)wCount, (LPARAM)lptbs);
   delete[] lptbs;
   return bRet;
}

BOOL CToolBar::SetButtonState(UINT idButton, UINT uState)
{
    assert (::IsWindow(m_hWnd));
    return SendMessage (m_hWnd, TB_SETSTATE, idButton, MAKELONG(uState, 0));
}
